﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace MultiBoxer
{

    
    class FFACE
    {
        private const string FFACE_LIBRARY = "FFACE.dll";

        #region PlayerInfo
        /// <summary>
        /// Player Jobs
        /// </summary>
        public enum Job : byte
        {
            NONE = 0,
            WAR = 1,
            MNK = 2,
            WHM = 3,
            BLM = 4,
            RDM = 5,
            THF = 6,
            PLD = 7,
            DRK = 8,
            BST = 9,
            BRD = 10,
            RNG = 11,
            SAM = 12,
            NIN = 13,
            DRG = 14,
            SMN = 15,
            BLU = 16,
            COR = 17,
            PUP = 18,
            DNC = 19,
            SCH = 20

        } // @ public enum Job : byte

        /// <summary>
        /// FFACE structure for an inventory item
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct INVENTORYITEM
        {
            public ushort ID;
            public byte Index;
            public uint Count;
            public uint Flag;
            public uint Price;
            public ushort Extra;

        } // @ public struct INVENTORYITEM

        /// <summary>
        /// Stats of the player
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PlayerStats
        {
            public short Str;
            public short Dex;
            public short Vit;
            public short Agi;
            public short Int;
            public short Mnd;
            public short Chr;

        } // @ public struct PlayerStats

        /// <summary>
        /// Element resistances of the player
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PlayerElements
        {
            public ushort Fire;
            public ushort Ice;
            public ushort Wind;
            public ushort Earth;
            public ushort Lightning;
            public ushort Water;
            public ushort Light;
            public ushort Dark;

        } // @ public struct PlayerElements

        /// <summary>
        /// Players Combat Skills
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PlayerCombatSkills
        {
            public ushort HandToHand;
            public ushort Dagger;
            public ushort Sword;
            public ushort GreatSword;
            public ushort Axe;
            public ushort GreatAxe;
            public ushort Scythe;
            public ushort Polearm;
            public ushort Katana;
            public ushort GreatKatana;
            public ushort Club;
            public ushort Staff;
            private ushort unkweap0;
            private ushort unkweap1;
            private ushort unkweap2;
            private ushort unkweap3;
            private ushort unkweap4;
            private ushort unkweap5;
            private ushort unkweap6;
            private ushort unkweap7;
            private ushort unkweap8;
            private ushort unkweap9;
            private ushort unkweap10;
            private ushort unkweap11;
            public ushort Archery;
            public ushort Marksmanship;
            public ushort Throwing;
            public ushort Guarding;
            public ushort Evasion;
            public ushort Shield;
            public ushort Parrying;

        } // @ public struct PlayerCombatSkills

        /// <summary>
        /// Players magic skills
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PlayerMagicSkills
        {
            public ushort Divine;
            public ushort Healing;
            public ushort Enhancing;
            public ushort Enfeebling;
            public ushort Elemental;
            public ushort Dark;
            public ushort Summon;
            public ushort Ninjitsu;
            public ushort Singing;
            public ushort String;
            public ushort Wind;
            public ushort BlueMagic;
            private ushort unkmagic0;
            private ushort unkmagic1;
            private ushort unkmagic2;
            private ushort unkmagic3;

        } // @ public struct PlayerMagicSkills

        /// <summary>
        /// Players craft skills
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PlayerCraftLevels
        {
            public ushort Fishing;
            public ushort Woodworking;
            public ushort Smithing;
            public ushort Goldsmithing;
            public ushort Clothcraft;
            public ushort Leathercraft;
            public ushort Bonecraft;
            public ushort Alchemy;
            public ushort Cooking;

        } // @ public struct PlayerCraftLevels
        #endregion

        #region StatusEffect

        /// <summary>
        /// Status effects
        /// </summary>
        public enum StatusEffect : ushort
        {
            KO = 0,
            Weakness = 1,
            Sleep = 2,
            Poison = 3,
            Paralysis = 4,
            Blindness = 5,
            Silence = 6,
            Petrification = 7,
            Disease = 8,
            Curse = 9,
            Stun = 10,
            Bind = 11,
            Weight = 12,
            Slow = 13,
            Charm1 = 14,
            Doom = 15,
            Amnesia = 16,
            Charm2 = 17,
            Terror = 28,
            Mute = 29,
            Bane = 30,
            Plague = 31,
            Flee = 32,
            Haste = 33,
            Blaze_Spikes = 34,
            Ice_Spikes = 35,
            Blink = 36,
            Stoneskin = 37,
            Shock_Spikes = 38,
            Aquaveil = 39,
            Protect = 40,
            Shell = 41,
            Regen = 42,
            Refresh = 43,
            Mighty_Strikes = 44,
            Boost = 45,
            Hundred_Fists = 46,
            Manafont = 47,
            Chainspell = 48,
            Perfect_Dodge = 49,
            Invincible = 50,
            Blood_Weapon = 51,
            Soul_Voice = 52,
            Eagle_Eye_Shot = 53,
            Meikyo_Shisui = 54,
            Astral_Flow = 55,
            Berserk = 56,
            Defender = 57,
            Aggressor = 58,
            Focus = 59,
            Dodge = 60,
            Counterstance = 61,
            Sentinel = 62,
            Souleater = 63,
            Last_Resort = 64,
            Sneak_Attack = 65,
            Copy_Image = 66,
            Third_Eye = 67,
            Warcry = 68,
            Invisible = 69,
            Deodorize = 70,
            Sneak = 71,
            Sharpshot = 72,
            Barrage = 73,
            Holy_Circle = 74,
            Arcane_Circle = 75,
            Hide = 76,
            Camouflage = 77,
            Divine_Seal = 78,
            Elemental_Seal = 79,
            STR_Boost1 = 80,
            DEX_Boost1 = 81,
            VIT_Boost1 = 82,
            AGI_Boost1 = 83,
            INT_Boost1 = 84,
            MND_Boost1 = 85,
            CHR_Boost1 = 86,
            Trick_Attack = 87,
            Max_HP_Boost = 88,
            Max_MP_Boost = 89,
            Accuracy_Boost = 90,
            Attack_Boost = 91,
            Evasion_Boost = 92,
            Defense_Boost = 93,
            Enfire = 94,
            Enblizzard = 95,
            Enaero = 96,
            Enstone = 97,
            Enthunder = 98,
            Enwater = 99,
            Barfire = 100,
            Barblizzard = 101,
            Baraero = 102,
            Barstone = 103,
            Barthunder = 104,
            Barwater = 105,
            Barsleep = 106,
            Barpoison = 107,
            Barparalyze = 108,
            Barblind = 109,
            Barsilence = 110,
            Barpetrify = 111,
            Barvirus = 112,
            Reraise = 113,
            Cover = 114,
            Unlimited_Shot = 115,
            Phalanx = 116,
            Warding_Circle = 117,
            Ancient_Circle = 118,
            STR_Boost2 = 119,
            DEX_Boost2 = 120,
            VIT_Boost2 = 121,
            AGI_Boost2 = 122,
            INT_Boost2 = 123,
            MND_Boost2 = 124,
            CHR_Boost2 = 125,
            Spirit_Surge = 126,
            Costume = 127,
            Burn = 128,
            Frost = 129,
            Choke = 130,
            Rasp = 131,
            Shock = 132,
            Drown = 133,
            Dia = 134,
            Bio = 135,
            STR_Down = 136,
            DEX_Down = 137,
            VIT_Down = 138,
            AGI_Down = 139,
            INT_Down = 140,
            MND_Down = 141,
            CHR_Down = 142,
            Level_Restriction = 143,
            Max_HP_Down = 144,
            Max_MP_Down = 145,
            Accuracy_Down = 146,
            Attack_Down = 147,
            Evasion_Down = 148,
            Defense_Down = 149,
            Physical_Shield = 150,
            Arrow_Shield = 151,
            Magic_Shield1 = 152,
            Damage_Spikes = 153,
            Shining_Ruby = 154,
            Medicine = 155,
            Flash = 156,
            Subjob_Restriction = 157,
            Provoke = 158,
            Penalty = 159,
            Preparations = 160,
            Sprint = 161,
            Enchantment = 162,
            Azure_Lore = 163,
            Chain_Affinity = 164,
            Burst_Affinity = 165,
            Overdrive = 166,
            Magic_Def_Down = 167,
            Inhibit_TP = 168,
            Potency = 169,
            Regain = 170,
            Pax = 171,
            Magic_Shield2 = 189,
            Magic_Atk_Boost = 190,
            Magic_Def_Boost = 191,
            Requiem = 192,
            Lullaby = 193,
            Elegy = 194,
            Paeon = 195,
            Ballad = 196,
            Minne = 197,
            Minuet = 198,
            Madrigal = 199,
            Prelude = 200,
            Mambo = 201,
            Aubade = 202,
            Pastoral = 203,
            Hum = 204,
            Fantasia = 205,
            Operetta = 206,
            Capriccio = 207,
            Serenade = 208,
            Round = 209,
            Gavotte = 210,
            Fugue = 211,
            Rhapsody = 212,
            Aria = 213,
            March = 214,
            Etude = 215,
            Carol = 216,
            Threnody = 217,
            Hymnus = 218,
            Mazurka = 219,
            Sirvente = 220,
            Auto_Regen = 233,
            Auto_Refresh = 234,
            Fishing_Imagery = 235,
            Woodworking = 236,
            Smithing = 237,
            Goldsmithing = 238,
            Clothcraft = 239,
            Leathercraft = 240,
            Bonecraft = 241,
            Alchemy = 242,
            Cooking = 243,
            Dedication = 249,
            Ef_Badge = 250,
            Food = 251,
            Chocobo = 252,
            Signet = 253,
            Battlefield = 254,
            Sanction = 256,
            Besieged = 257,
            Illusion = 258,
            No_Weapons_Armor = 259,
            No_Support_Job = 260,
            No_Job_Abilities = 261,
            No_Magic_Casting = 262,
            Penalty_to_Attribute_s_ = 263,
            Overload = 299,
            Fire_Maneuver = 300,
            Ice_Maneuver = 301,
            Wind_Maneuver = 302,
            Earth_Maneuver = 303,
            Thunder_Maneuver = 304,
            Water_Maneuver = 305,
            Light_Maneuver = 306,
            Dark_Maneuver = 307,
            Doubleup_Chance = 308,
            Bust = 309,
            Fighters_Roll = 310,
            Monks_Roll = 311,
            Healers_Roll = 312,
            Wizards_Roll = 313,
            Warlocks_Roll = 314,
            Rogues_Roll = 315,
            Gallants_Roll = 316,
            Chaos_Roll = 317,
            Beast_Roll = 318,
            Choral_Roll = 319,
            Hunters_Roll = 320,
            Samurai_Roll = 321,
            Ninja_Roll = 322,
            Drachen_Roll = 323,
            Evokers_Roll = 324,
            Maguss_Roll = 325,
            Corsairs_Roll = 326,
            Puppet_Roll = 327,
            Warriors_Charge = 340,
            Formless_Strikes = 341,
            Assassins_Charge = 342,
            Feint = 343,
            Fealty = 344,
            Dark_Seal = 345,
            Diabolic_Eye = 346,
            Nightingale = 347,
            Troubadour = 348,
            Killer_Instinct = 349,
            Stealth_Shot = 350,
            Flashy_Shot = 351,
            Sange = 352,
            Hasso = 353,
            Seigan = 354,
            Convergence = 355,
            Diffusion = 356,
            Snake_Eye = 357,
            Light_Arts = 358,
            Dark_Arts = 359,
            Penury = 360,
            Parsimony = 361,
            Celerity = 362,
            Alacrity = 363,
            Rapture = 364,
            Ebullience = 365,
            Accession = 366,
            Manifestation = 367,
            Drain_Samba = 368,
            Aspir_Samba = 369,
            Haste_Samba = 370,
            Velocity_Shot = 371,
            Building_Flourish = 375,
            Trance = 376,
            Tabula_Rasa = 377,
            Drain_Daze = 378,
            Aspir_Daze = 379,
            Haste_Daze = 380,
            Finishing_Move1 = 381,
            Finishing_Move2 = 382,
            Finishing_Move3 = 383,
            Finishing_Move4 = 384,
            Finishing_Move5 = 385,
            Lethargic_Daze1 = 386,
            Lethargic_Daze2 = 387,
            Lethargic_Daze3 = 388,
            Lethargic_Daze4 = 389,
            Lethargic_Daze5 = 390,
            Sluggish_Daze1 = 391,
            Sluggish_Daze2 = 392,
            Sluggish_Daze3 = 393,
            Sluggish_Daze4 = 394,
            Sluggish_Daze5 = 395,
            Weakened_Daze1 = 396,
            Weakened_Daze2 = 397,
            Weakened_Daze3 = 398,
            Weakened_Daze4 = 399,
            Weakened_Daze5 = 400,
            Addendum_White = 401,
            Addendum_Black = 402,
            Reprisal = 403,
            Magic_Evasion_Down = 404,
            Retaliation = 405,
            Footwork = 406,
            Klimaform = 407,
            Sekkanoki = 408,
            Pianissimo = 409,
            Saber_Dance = 410,
            Fan_Dance = 411,
            Altruism = 412,
            Focalization = 413,
            Tranquility = 414,
            Equanimity = 415,
            Enlightenment = 416,
            Afflatus_Solace = 417,
            Afflatus_Misery = 418,
            Composure = 419

        } // @ public enum StatusEffect : short

        /// <summary>
        /// Structure passed back from FFACE.GetPlayerInfo()
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PLAYERINFO
        {
            public int HPMax;
            public int MPMax;
            public Job MainJob;
            public byte MainJobLVL;
            public Job SubJob;
            public byte SubJobLVL;
            public ushort EXPIntoLVL;
            public ushort EXPForLVL;
            public PlayerStats Stats;
            public PlayerStats StatModifiers;
            public short Attack;
            public short Defense;
            public PlayerElements Elements;
            public short Title;
            public short Rank;
            public short RankPts;
            public byte Nation;
            public byte Residence;
            public int HomePoint;
            public PlayerCombatSkills CombatSkills;
            public PlayerMagicSkills MagicSkills;
            public PlayerCraftLevels CraftLevels;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 146)]
            private byte[] null0;
            public ushort LimitPoints;
            public byte MeritPoints;
            public byte LimitMode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 78)]
            private byte[] null1;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public StatusEffect[] Buffs;

        } // @ private struct PLAYERINFO
        #endregion

        #region PartyMember

        /// <summary>
        /// FFACE structure for a party member
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PARTYMEMBER
        {
            public int pad0;
            public byte Index;
            public byte MemberNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
            public string Name;
            public int SvrID;
            public int ID;
            private int unknown0;
            public int CurrentHP;
            public int CurrentMP;
            public int CurrentTP;
            public byte CurrentHPP;
            public byte CurrentMPP;
            public short Zone;
            private int pad1;
            public uint FlagMask;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            private byte[] pad2;
            public int SvrIDDupe;
            public byte CurrentHPPDupe;
            public byte CurrentMPPDupe;
            public bool Active;
            private byte pad3;

        } // @ private struct PARTYMEMBER

        #endregion


        
        
        [DllImport(FFACE_LIBRARY, EntryPoint = "CreateInstance")]
        public static extern int CreateInstance(UInt32 PID);


        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSelectedItemNum")]
        public static extern int GetSelectedItemNum(int instance);

        [DllImport(FFACE_LIBRARY, EntryPoint = "GetPLayerServerID")]
        public static extern int GetPLayerServerID(int instance);

        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSelectedItemIndex")]
        public static extern int GetSelectedItemIndex(int instance);

        [DllImport(FFACE_LIBRARY, EntryPoint = "MenuSelection")]
        public static extern void MenuSelection(int instance, byte[] buffer, ref int size);

        [DllImport(FFACE_LIBRARY, EntryPoint = "MenuHelp")]
        public static extern void MenuHelp(int instance, byte[] buffer, ref int size);

        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void GetPlayerInfo(int instanceID, ref PLAYERINFO playerInfo);


        [DllImport(FFACE_LIBRARY, EntryPoint = "GetInventoryMax")]
        public static extern int GetInventoryMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSafeMax")]
        public static extern int GetSafeMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetStorageMax")]
        public static extern int GetStorageMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetTempMax")]
        public static extern int GetTempMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetLockerMax")]
        public static extern int GetLockerMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSatchelMax")]
        public static extern int GetSatchelMax(int instance);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSackMax")]
        public static extern int GetSackMax(int instance);

        [DllImport(FFACE_LIBRARY, EntryPoint = "GetInventoryItem")]
        public static extern INVENTORYITEM InventoryItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSafeItem")]
        public static extern INVENTORYITEM SafeItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetStorageItem")]
        public static extern INVENTORYITEM StorageItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetTempItem")]
        public static extern INVENTORYITEM TempItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetLockerItem")]
        public static extern INVENTORYITEM LockerItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSatchelItem")]
        public static extern INVENTORYITEM SatchelItem(int instance, int index);
        [DllImport(FFACE_LIBRARY, EntryPoint = "GetSackItem")]
        public static extern INVENTORYITEM SackItem(int instance, int index);


        /// <summary>
        /// FFACE 4.0.0.9 import to get a party members information
        /// </summary>
        /// <param name="instance">Instance ID generated by FFACE</param>
        /// <param name="index">Index of party member</param>
        /// <param name="partyMember">Information returned by reference about party member</param>
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void GetPartyMember(int instanceID, byte index, ref PARTYMEMBER partyMember);

        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void DeleteInstance(int instanceID);


        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHCreateTextObject(int instanceID, string name);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetText(int instanceID, string name, string data);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetColor(int instanceID, string name, byte transparent, byte red, byte green, byte blue);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetLocation(int instanceID, string name, float vertical, float horizontal);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetVisibility(int instanceID, string name, bool visible);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHFlushCommands(int instanceID);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHDeleteTextObject(int instanceID, string name);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetBold(int instanceID, string name, bool bold);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetItalic(int instanceID, string name, bool italic);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetBGColor(int instanceID, string name, byte transparent, byte red, byte green, byte blue);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetBGBorderSize(int instanceID, string name, float pixels);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetBGVisibility(int instanceID, string name, bool visible);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetRightJustified(int instanceID, string name, bool justified);
        [DllImport(FFACE_LIBRARY, CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern void CTHSetFont(int instanceID, string name, string font, short height);


    }
}
